package com.marvels.approve.credit.service.impl;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.druid.sql.visitor.functions.Now;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.util.StringUtil;
import com.marvels.approve.common.dto.QuicklyAddListDetails;
import com.marvels.approve.common.dto.QuicklyAddResponse;
import com.marvels.approve.common.service.IUploadFileService;
import com.marvels.approve.common.service.McamLoanApplyInfoCommonService;
import com.marvels.approve.credit.consum.ConsumerExternalIntBankApi;
import com.marvels.approve.credit.dao.CreditDao;
import com.marvels.approve.credit.dao.EdcBurialPointMsgDao;
import com.marvels.approve.credit.dao.McamAttachmentInfoDao;
import com.marvels.approve.credit.dto.CreditExcelDTO;
import com.marvels.approve.credit.dto.EdcBurialPointMsgDTO;
import com.marvels.approve.credit.dto.IntBankLogDTO;
import com.marvels.approve.credit.dto.McamAttachmentInfoDTO;
import com.marvels.approve.credit.service.ApproveThirdCreditReportService;
import com.marvels.approve.credit.service.CreditReportService;
import com.marvels.approve.loan.dao.IMcamLoanApplyInfoDao;
import com.marvels.approve.loan.dto.McamAcLoanApplyImageInfo;
import com.marvels.approve.loan.dto.McamLoanApplyInfoDTO;
import com.marvels.approve.manager.dto.ActivitiNodeDTO;
import com.marvels.approve.manager.dto.OpinionDTO;
import com.marvels.approve.manager.dto.OpinionTypeDTO;
import com.marvels.approve.manager.service.IOpinionService;
import com.marvels.approve.manager.service.IOpinionTypeService;
import com.marvels.approve.process.dao.AttachmentInfoDao;
import com.marvels.approve.process.dao.ILoanApplyCaseDao;
import com.marvels.approve.process.dto.CompleteProcessDTO;
import com.marvels.approve.process.dto.HandleProcessDTO;
import com.marvels.approve.process.dto.LaAttachAtmeTypeViewDTO;
import com.marvels.approve.process.dto.LoanApplyCaseDTO;
import com.marvels.approve.process.dto.ProcessApproveDTO;
import com.marvels.approve.process.dto.ScreenshotsDTO;
import com.marvels.approve.process.service.IProcessService;

import com.marvels.common.constants.CaseNodeConstant;
import com.marvels.common.constants.LoanCaseStatusConstant;
import com.marvels.common.constants.LoanStateConstant;
import com.marvels.common.constants.MarvelsConstant;
import com.marvels.common.constants.OpinionConstant;
import com.marvels.common.constants.PageConstant;
import com.marvels.common.constants.PatternType;
import com.marvels.common.dto.UserDTO;
import com.marvels.common.exception.MarvelsBusinessException;
import com.marvels.common.utils.CacheUtils;
import com.marvels.common.utils.MarvelsLogUtil;
import com.marvels.common.utils.MarvelsUtils;
import com.marvels.common.utils.ServerProperties;
import com.marvels.common.utils.StringUtils;

@Service
public class CreditReportServiceImpl implements CreditReportService {
	@Autowired
	private CreditReportService creditReportService;

	@Autowired
	private McamAttachmentInfoDao mcamAttachmentInfoDao;
	@Autowired
	private ILoanApplyCaseDao loanApplyCaseDao;
	@Autowired
	private CreditDao creditDao;
	@Autowired
	private IProcessService processService;
	
	@Autowired
	private IMcamLoanApplyInfoDao mcamLoanApplyInfoDao;
	
	@Autowired
	private ApproveThirdCreditReportService thirdCreditReportService;
	
	@Autowired
	private IOpinionService opinionService;
	
	@Autowired
	private IOpinionTypeService opinionTypeService;
	
	@Autowired
	private ConsumerExternalIntBankApi consumerExternalIntBankApi;
	@Autowired
	private IUploadFileService uploadFileService;
	@Autowired
	private AttachmentInfoDao attachmentInfoMapper;
	@Value("${config.properties.path}")
	private String configPropertiesPath;
	
	@Value("${marvels.file.upload.basepath}")
	private String fileBasePath ; // 共享文件服务器 文件基地址
	
	@Autowired
	private EdcBurialPointMsgDao edcBurialPointMsgDao;
	
	@Autowired
	private McamLoanApplyInfoCommonService mcamLoanApplyInfoCommonService;
	
	@Override
	public List<McamAttachmentInfoDTO> getUserMediaByLoanId(String loanId) throws MarvelsBusinessException {
		List<McamAttachmentInfoDTO> atmtList = mcamAttachmentInfoDao.getUserMediaByLoanId(loanId);
		return atmtList;
	}

	@Override
	public PageInfo<LoanApplyCaseDTO> getPageInfoByCondition(LoanApplyCaseDTO param) throws MarvelsBusinessException {
		MarvelsLogUtil.getInstance().info("入参" + param);
		PageHelper.startPage(param.getPageNum(), param.getPageSize());
		param.setAssignee(param.obtainLoginUserName());
		List<LoanApplyCaseDTO> caseList = creditDao.getCreditList(param);
		PageInfo<LoanApplyCaseDTO> pageInfo = new PageInfo<LoanApplyCaseDTO>(caseList);
		return pageInfo;

	}

	@Override
	public LoanApplyCaseDTO getUserBaseInfoByLoanId(String loanId) throws MarvelsBusinessException {
		return loanApplyCaseDao.getEntity(loanId,LoanCaseStatusConstant.ZHAPP);
	}
	
	@Override
	public LoanApplyCaseDTO getUserBaseInfoByNodeCode(String loanId,String nodeCode) throws MarvelsBusinessException {
		// TODO Auto-generated method stub
		return loanApplyCaseDao.getEntityByNodeCode(loanId,nodeCode);
	}

	/**
	 * 征信阶段 成功转到下一节点 woCreditInspection->woCreditLoadUp,
	 * woCreditLoadUp->woCreditCheck, woCreditCheck->woCreditCheckBefore,woCreditCheckBefore->woChecking
	 */
	@Override
	@Transactional(timeout = 30 ,rollbackFor = Exception.class)
	public LoanApplyCaseDTO commitToNextNode(LoanApplyCaseDTO caseInfo) throws MarvelsBusinessException {
		if (caseInfo == null)
			throw new MarvelsBusinessException("进件不存在!");

		CompleteProcessDTO proDto = new CompleteProcessDTO();

		ProcessApproveDTO processApproveDto = new ProcessApproveDTO();

		processApproveDto.setProcessResult(MarvelsConstant.PROCESS_RESULT_OK);
		processApproveDto.setLoanId(caseInfo.getLoanId());
		proDto.setProcessApproveDto(processApproveDto);

		proDto.setLoanId(caseInfo.getLoanId());

		return processService.completeLoanApplyCase(proDto);
	}
	/**
	 * 单子否决
	 */
	@Override
	@Transactional(timeout = 30 ,rollbackFor = Exception.class)
	public void vetoCase(LoanApplyCaseDTO param) throws MarvelsBusinessException {
		//更新进件状态
		mcamLoanApplyInfoCommonService.updateMcamLoanApplyInfoStatusByLoanId(param.getLoanId(), LoanStateConstant.ZR0,LoanStateConstant.J07, param.obtainLoginUserName());
		
		LoanApplyCaseDTO caseInfo = loanApplyCaseDao.getEntityByLoanId(param.getLoanId());
		CompleteProcessDTO proDto = new CompleteProcessDTO();
		Map<String, Object> variables = new HashMap<String, Object>();
		// 流程状态置为否决
		variables.put("processResult", MarvelsConstant.PROCESS_RESULT_REFUSE);
		proDto.setLoanId(param.getLoanId());
		ActivitiNodeDTO curNode = new ActivitiNodeDTO();
		curNode.setNodeCode(caseInfo.getCurNodeCode());
		// 设置当前所处节点
		proDto.setCurNode(curNode);
		processService.completeLoanApplyCase(proDto);
		
		// 记录审批意见信息
		OpinionDTO opinionDTO = new OpinionDTO();
		opinionDTO.setLoanId(param.getLoanId());
		UserDTO user = CacheUtils.getCacheUser();
		opinionDTO.setCreatedBy(user.getUserCode());
		opinionDTO.setUpdatedBy(user.getUserCode());
		opinionDTO.setOpinion(param.getBackReason());
		opinionDTO.setCaseVersion(caseInfo.getCaseVersion());
		opinionDTO.setNodeCode(caseInfo.getCurNodeCode());
		opinionDTO.setOpinionClass(OpinionConstant.OPINIONREFUSE);
		opinionService.saveOpinion(opinionDTO);
	}

	/**
	 * 征信录入退回
	 * 
	 * @param param
	 */
	@Override
	@Transactional(timeout = 30 ,rollbackFor = Exception.class)
	public void chargeBack(McamLoanApplyInfoDTO param,String caseNode,String loanStatus) throws MarvelsBusinessException {
		if (param == null) {
			throw new MarvelsBusinessException("该笔单子不存在!");
		}
		MarvelsLogUtil.getInstance().info(param.obtainLoginUserName() + "对单号:" + param.getLoanId() + "执行了征信录入退回操作");
		LoanApplyCaseDTO caseInfo = loanApplyCaseDao.getEntityByLoanId(param.getLoanId());
		if (caseInfo == null) {
			throw new MarvelsBusinessException("该笔单子流程信息不存在!");
		}
		// 退回
		CompleteProcessDTO proDto = new CompleteProcessDTO();
		ProcessApproveDTO processApproveDto = new ProcessApproveDTO();
		processApproveDto.setProcessResult(caseNode);
		processApproveDto.setLoanId(param.getLoanId());
		proDto.setProcessApproveDto(processApproveDto);
		proDto.setLoanId(param.getLoanId());
		LoanApplyCaseDTO caseDTO = processService.completeLoanApplyCase(proDto);

		// 更新进件表状态
//		McamLoanApplyInfoDTO infoDTO=new McamLoanApplyInfoDTO();
//		infoDTO.setStatus(returnNode);
//		infoDTO.setLoanId(param.getLoanId());
//		this.mcamLoanApplyInfoDao.updateByLoanId(infoDTO);
		mcamLoanApplyInfoCommonService.updateMcamLoanApplyInfoStatusByLoanId(param.getLoanId(), loanStatus,null, param.obtainLoginUserName());

		// 记录退回信息
//		creditDao.chargeBack(param);
		
		if(StringUtils.isNotEmpty(param.getBackReasonCodes())){
			List<String> backReasons = Arrays.asList(param.getBackReasonCodes().split(","));
			List<OpinionTypeDTO> returnOpinionTypes = getReturnOpinionTypes();
			for(String reason : backReasons){
				for(OpinionTypeDTO opinionType : returnOpinionTypes){
					if(reason.equals(opinionType.getOpinionTypeCode())){
						OpinionDTO opinion = new OpinionDTO();
						opinion.setLoanId(param.getLoanId());
						opinion.setCaseVersion(caseDTO.getCaseVersion());
						opinion.setCaseResult(caseNode);
						opinion.setNodeCode(caseDTO.getCurNodeCode());
						opinion.setNodeName(caseDTO.getCurNodeName());
						opinion.setOpinionTypeCode(opinionType.getOpinionTypeCode());
						opinion.setOpinionTypeName(opinionType.getOpinionTypeName());
						opinion.setOpinionTypeApp(opinionType.getOpinionTypeApp());	
						opinion.setOpinion(param.getBackReason());
						opinion.setOpinionClass(opinionType.getOpinionClass());
						opinion.setCreatedBy(opinion.obtainLoginUserName());
						opinion.setUpdatedBy(opinion.obtainLoginUserName());
						this.opinionService.saveOpinion(opinion);
						break;
					}
				}
				
			}
//			caseDTO.setBackReasonCodes(backReasons);
//			this.saveOpinion(caseDTO, caseNode, param.getBackReason(),OpinionConstant.OPINIONRETURN);
		}
		else if(!StringUtils.isEmpty(param.getBackReason())){//页面只有填备注，没有原因选项的情况
			// 记录审批意见信息
			OpinionDTO opinionDTO = new OpinionDTO();
			opinionDTO.setLoanId(caseDTO.getLoanId());
			UserDTO user = CacheUtils.getCacheUser();
			opinionDTO.setCreatedBy(user.getUserCode());
			opinionDTO.setUpdatedBy(user.getUserCode());
			opinionDTO.setOpinion(param.getBackReason());
			opinionDTO.setCaseVersion(caseDTO.getCaseVersion());
			opinionDTO.setNodeCode(caseInfo.getCurNodeCode());
			opinionDTO.setOpinionClass(OpinionConstant.OPINIONRETURN);
			this.opinionService.saveOpinion(opinionDTO);
		}
	}
	/**
	 * 记录审批意见
	 * @param caseDTO
	 * @param caseResult
	 * @param opinion
	 * @param opinionType
	 * @throws MarvelsBusinessException
	 */
	private void saveOpinion(LoanApplyCaseDTO caseDTO,String caseResult,String opinion,Integer opinionType) throws MarvelsBusinessException{
		//获取初始化类型选项
		Map<Integer,List<OpinionTypeDTO>> allOpinionTypes = this.opinionTypeService.getOpinionTypes(CaseNodeConstant.WOCHECKINGBEFORE.getCode());
		List<OpinionTypeDTO> approveOpinionTypes = allOpinionTypes.get(opinionType);
		if(!CollectionUtils.isEmpty(approveOpinionTypes) && !CollectionUtils.isEmpty(caseDTO.getBackReasonCodes())){
			int size = caseDTO.getBackReasonCodes().size();
			for (OpinionTypeDTO opinionTypeDTO : approveOpinionTypes) {
				for (int i = 0; i < size; i++) {
					if(opinionTypeDTO.getOpinionTypeCode().equals(caseDTO.getBackReasonCodes().get(i))){
						// 记录审批意见信息
						OpinionDTO opinionDTO = new OpinionDTO();
						opinionDTO.setLoanId(caseDTO.getLoanId());
						opinionDTO.setCaseVersion(caseDTO.getCaseVersion());
						opinionDTO.setCaseResult(caseResult);
						opinionDTO.setNodeCode(caseDTO.getCurNodeCode());// 节点代码
						opinionDTO.setNodeName(caseDTO.getCurNodeName());// 节点名称
						UserDTO user = CacheUtils.getCacheUser();
						opinionDTO.setCreatedBy(user.getUserCode());
						opinionDTO.setUpdatedBy(user.getUserCode());
						opinionDTO.setOpinion(opinion);
						opinionDTO.setOpinionClass(opinionTypeDTO.getOpinionClass());//意见分类 0 拒绝 1违例 2复核意见 3审批确认 4退回',
						opinionDTO.setOpinionTypeApp(opinionTypeDTO.getOpinionTypeApp());
						opinionDTO.setOpinionTypeCode(opinionTypeDTO.getOpinionTypeCode());
						opinionDTO.setOpinionTypeName(opinionTypeDTO.getOpinionTypeName());
						this.opinionService.saveOpinion(opinionDTO);
					}
				}
			}
		}
	}
	/**
	 * 征信报告上传
	 */
	@Override
	@Transactional(timeout = 30 ,rollbackFor = Exception.class)
	public void creditReportUpload(InputStream uploadStream, String loanId) throws MarvelsBusinessException {
		LoanApplyCaseDTO caseInfo = loanApplyCaseDao.getEntityByNodeCode(loanId, CaseNodeConstant.WOCREDITLOADUP.getCode());
		// 上传附件文件的本地保存
		Integer attachmentState;
		try {
			attachmentState = saveCreditReportFile(uploadStream, loanId, caseInfo.obtainLoginUserName());
		} catch (IOException e) {
			throw new MarvelsBusinessException("征信报告上传异常",e);
		}
		if(attachmentState < 1){
			throw new MarvelsBusinessException("征信报告上传失败!");
		}
		//流程节点的流转到下一节点
		commitToNextNode(caseInfo);
		
	}

	private Integer saveCreditReportFile(InputStream uploadStream, String loanId, String createBy) throws MarvelsBusinessException, IOException {
		McamAttachmentInfoDTO param = new McamAttachmentInfoDTO();
		param.setLoanId(loanId);
		param.setUpdatedBy(createBy);
		param.setAtmtType("PDF_B");
		//删除旧的附件
		mcamAttachmentInfoDao.deleteAttachmentInfoByAtmtType(param);
		// 对文件的征信报告上传
		McamAttachmentInfoDTO attachment = new McamAttachmentInfoDTO();
		attachment.setAtmtType("PDF_B");
		attachment.setLoanId(loanId);
		attachment.setAtmtTypeName("征信报告");
		attachment.setCreatedBy(createBy);
		attachment.setUpdatedBy(createBy);
		// ----征信报告改名
		Date date = new Date();
		DateFormat df = new SimpleDateFormat("yyyyMMdd_HHmmssSSS");
		String time = df.format(date);

		String pdfName = time + "_credit.pdf";
		String prefix = MarvelsUtils.getPathPrefix();
		String basePath = fileBasePath+MarvelsConstant.UPLOAD_FILE_PATH_PDF;
		attachment.setFileLocation(basePath + prefix + pdfName);
		attachment.setFileName(pdfName);
		attachment.setUploadTime(date);
		attachment.setUploadUserId(createBy);
		Integer attachmentState = 0;
		
		IntBankLogDTO intBankLogDTO = new IntBankLogDTO();
		UserDTO user = CacheUtils.getCacheUser();
		intBankLogDTO.setLoanId(loanId);
		intBankLogDTO.setCount(1);
		intBankLogDTO.setCreatedBy(user.getUserCode());
		intBankLogDTO.setUpdatedBy(user.getUserCode());
		intBankLogDTO.setCreatedDate(new Date());
		intBankLogDTO.setUpdatedDate(new Date());
		intBankLogDTO.setPath(attachment.getFileLocation());
		intBankLogDTO.setCreatedName(attachment.getFileName());
		attachmentState = consumerExternalIntBankApi.insertIntBankLog(intBankLogDTO);//上传征信报告，保存日志
		if(attachmentState < 1){
			throw new MarvelsBusinessException("记录征信报告上传日志失败!");
		}
		// 附件表数据新增
		attachmentState = mcamAttachmentInfoDao.insertItem(attachment);
		if(attachmentState < 1){
			throw new MarvelsBusinessException("征信报告储存失败!");
		}
		File directory = new File(basePath + prefix);
		if (directory.exists() == false) {
			directory.mkdirs();
		}
		File creditFile = new File(attachment.getFileLocation());
		creditFile.deleteOnExit();
		creditFile.createNewFile();
		MarvelsUtils.streamToFile(uploadStream, creditFile);
		return attachmentState;
	}

	@Override
	public Integer getWaitForDealCount(LoanApplyCaseDTO param) {
		return creditDao.getWaitForDealCount(param);
	}

	@Override
	public PageInfo<LoanApplyCaseDTO> getApproveFinishList(LoanApplyCaseDTO param) throws MarvelsBusinessException {
		MarvelsLogUtil.getInstance().info("入参" + param);
		Integer pageNum = param.getPageNum() == null ? PageConstant.CURRPAGE : param.getPageNum();

		Integer pageSize = param.getPageSize() == null ? PageConstant.PAGESIZE : param.getPageSize();

		PageHelper.startPage(pageNum, pageSize);
		
		List<LoanApplyCaseDTO> caseList = creditDao.getApproveFinishList(param);

		PageInfo<LoanApplyCaseDTO> pageInfo = new PageInfo<LoanApplyCaseDTO>(caseList);

		return pageInfo;
	}


	/**
	 * 下载映像文件
	 * 
	 * @throws MarvelsBusinessException
	 */
	@Override
	public void downLoadMedia(String loanId, HttpServletRequest request, HttpServletResponse response)
			throws MarvelsBusinessException {
		MarvelsLogUtil.getInstance().info("入参" + loanId);
		Date date = new Date();
		DateFormat df = new SimpleDateFormat("yyyyMMdd_HHmmssSSS");
		String time = df.format(date);

		String str = time + "_credit_info";
		// 打包
		try {
			zipFile(str, loanId, request);
			String FilePath = request.getSession().getServletContext().getRealPath("/");
			String path = FilePath + str + ".zip";
			File file = new File(path);
			response.setCharacterEncoding("UTF-8");
			response.setContentType("application/x-download;charset=utf-8");// 设置response内容的类型
			if (file.exists()) {
				response.setHeader("Content-disposition","attachment;filename=" + new String(file.getName().getBytes(), "ISO8859-1"));// 设置头部信息
				InputStream ins = new FileInputStream(file);
				BufferedInputStream bins = new BufferedInputStream(ins);// 放到缓冲流里面
				OutputStream outs = response.getOutputStream();// 获取文件输出IO流
				BufferedOutputStream bouts = new BufferedOutputStream(outs);
				int bytesRead = 0;
				byte[] buffer = new byte[8192];
				// 开始向网络传输文件流
				while ((bytesRead = bins.read(buffer, 0, 8192)) != -1) {
					bouts.write(buffer, 0, bytesRead);
				}
				bouts.flush();// 这里一定要调用flush()方法
				ins.close();
				bins.close();
				outs.close();
				bouts.close();
				MarvelsLogUtil.getInstance().info("文件下载成功");
			} else {
				response.setHeader("Content-disposition", "attachment;filename=信息未找到.txt");
				response.getWriter().print("未找到数据，请确认！");
			}
		} catch (Exception e) {
			e.printStackTrace();
			MarvelsLogUtil.getInstance().info("下载出错了！");
			throw new MarvelsBusinessException("下载出场了！");
		} finally {
			String FilePath = request.getSession().getServletContext().getRealPath("/");
			String path = FilePath + str + ".zip";
			File file = new File(path);
			boolean delete = file.delete();
			if (delete) {
				MarvelsLogUtil.getInstance().info("loanId为" + loanId + "的临时文件删除成功!");
			}
		}
	}

	/**
	 * 打包压缩文件到本地
	 * 
	 * @param str
	 */
	private void zipFile(String zipFileName, String loanId, HttpServletRequest request) throws IOException {
		MarvelsLogUtil.getInstance().info("打包下载loanId为" + loanId + "的信息");
		// 获取图片url集合
		List<String> urlList = new ArrayList<String>();
		List<McamAttachmentInfoDTO> attaments = mcamAttachmentInfoDao.getUserImageByLoanId(loanId);
		for (McamAttachmentInfoDTO attachment : attaments) {
			urlList.add(attachment.getFileLocation());
		}
		String filePath = request.getSession().getServletContext().getRealPath("/");
		String zipFile = filePath + zipFileName + ".zip";
		byte[] buffer = new byte[1024];
		// 定义一个zip输出流
		ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFile));
		for (String url : urlList) {
			if (!StringUtils.isEmpty(url)) {
				File file = new File(url);
				if (file.exists()) {
					FileInputStream fis = new FileInputStream(file);
					zipOut.putNextEntry(new ZipEntry(file.getName()));
					int len;
					// 读入需要下载的文件的内容，打包到zip文件
					while ((len = fis.read(buffer)) > 0) {
						zipOut.write(buffer, 0, len);
					}
					zipOut.closeEntry();
					fis.close();
				}
			}
		}
		zipOut.close();
	}


	@Override
	public HSSFWorkbook downloadCreditExcel(CreditExcelDTO param,HttpServletRequest request, HttpServletResponse response) throws MarvelsBusinessException, IOException {
		response.setCharacterEncoding("UTF-8");
		response.setContentType("application/vnd.ms-excel");
		param.setCurNodeCode(CaseNodeConstant.WOCREDITLOADUP.getCode());
		List<Map<String, Object>> list = creditDao.queryCreditExcel(param);
		HSSFWorkbook workbook  = getCreditExcel(list);
		return workbook;
	}

	public HSSFWorkbook getCreditExcel(List<Map<String, Object>> list) {
		HSSFWorkbook wb = new HSSFWorkbook();
		HSSFSheet sheet = wb.createSheet("放款审核数据一览表");
		HSSFRow row = sheet.createRow((int) 0);
		sheet.setDefaultColumnWidth(10);
		// 创建单元格，并设置值表头 设置表头居中
		HSSFCellStyle style = wb.createCellStyle();
		// 居中格式、加粗
		style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
		HSSFFont font = wb.createFont();
		font.setFontHeightInPoints((short) 11);
		font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
		style.setBorderBottom((short) 1);// 下边框
		style.setBorderLeft((short) 1);// 左边框
		style.setBorderRight((short) 1);// 右边框
		style.setBorderTop((short) 1);// 上边框
		style.setLocked(true);
		style.setFont(font);
		// 设置表内容格式
		HSSFCellStyle style2 = wb.createCellStyle();
		style2.setBorderBottom((short) 1);// 下边框
		style2.setBorderLeft((short) 1);// 左边框
		style2.setBorderRight((short) 1);// 右边框
		style2.setBorderTop((short) 1);// 上边框
		style2.setAlignment(HSSFCellStyle.ALIGN_CENTER);
		HSSFCell cell = row.createCell(0);
		cell.setCellValue("进件日期");
		cell.setCellStyle(style);
		cell = row.createCell(1);
		cell.setCellValue("申请书编号");
		cell.setCellStyle(style);
		cell = row.createCell(2);
		cell.setCellValue("客户姓名");
		cell.setCellStyle(style);
		cell = row.createCell(3);
		cell.setCellValue("身份证号");
		cell.setCellStyle(style);
		cell = row.createCell(4);
		cell.setCellValue("民族");
		cell.setCellStyle(style);
		cell = row.createCell(5);
		cell.setCellValue("通讯地址");
		cell.setCellStyle(style);
		cell = row.createCell(6);
		cell.setCellValue("证件签发机关");
		cell.setCellStyle(style);
		cell = row.createCell(7);
		cell.setCellValue("证件有效时间");
		cell.setCellStyle(style);
		cell = row.createCell(8);
		cell.setCellValue("联系电话");
		cell.setCellStyle(style);

		List<Map<String, Object>> datas = list;
		if (datas != null && datas.size() > 0) {
			for (int i = 0; i < datas.size(); i++) {
				Map<String, Object> map = datas.get(i);
				row = sheet.createRow((int) i + 1);
				// 创建单元格，并设置值
				Object commit_time = (Object) map.get("createdDate");
				if (commit_time == null) {
					row.createCell(0).setCellValue("");
				} else {
					row.createCell(0).setCellValue(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(commit_time));
				}
				row.createCell(1).setCellValue(check(map.get("loanId") + ""));
				row.createCell(2).setCellValue(check(map.get("custName") + ""));
				row.createCell(3).setCellValue(check(map.get("custCardNo") + ""));
				row.createCell(4).setCellValue(check(map.get("custNationalityName") + ""));
				row.createCell(5).setCellValue(check(map.get("curHomeAddress") + ""));
				row.createCell(6).setCellValue(check(map.get("custCardIssuer") + ""));

				Object applicant_id_stt = (Object) map.get("custCardStartTime");
				Object applicant_id_exp = (Object) map.get("custCardEndTime");
				if (commit_time != null) {
					applicant_id_stt = new SimpleDateFormat("yyyy.MM.dd").format(applicant_id_stt);
				} else {
					applicant_id_stt = "";
				}
				if (applicant_id_exp != null) {
					applicant_id_exp = new SimpleDateFormat("yyyy.MM.dd").format(applicant_id_exp);
				} else {
					applicant_id_exp = "";
				}
				row.createCell(7).setCellValue(applicant_id_stt + "-" + applicant_id_exp);
				row.createCell(8).setCellValue(check(map.get("mobileNo") + ""));

				for (int j = 0; j < 8; j++) {
					row.getCell(j).setCellStyle(style2);
				}
			}
		}
		return wb;
	}

	public String check(String row) {
		if (row == null) {
			row = "";
		} else if ("null".equals(row)) {
			row = "";
		}
		return row;
	}

	
	
	public HSSFWorkbook getAcquisitionExcel(List<QuicklyAddListDetails> list){
		HSSFWorkbook wb = new HSSFWorkbook();    
	       HSSFSheet sheet = wb.createSheet("快加查询清单");    
	       HSSFRow row = sheet.createRow((int) 0);   
	       sheet.setDefaultColumnWidth(10);  
	       // 创建单元格，并设置值表头 设置表头居中    
	       HSSFCellStyle style = wb.createCellStyle();    
	       // 居中格式、加粗    
	       style.setAlignment(HSSFCellStyle.ALIGN_CENTER);   
	       HSSFFont font = wb.createFont();  
	       font.setFontHeightInPoints((short) 11);  
	       font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);  
	       style.setBorderBottom((short) 1);// 下边框    
	       style.setBorderLeft((short) 1);// 左边框    
	       style.setBorderRight((short) 1);// 右边框    
	       style.setBorderTop((short) 1);// 上边框    
	       style.setLocked(true);  
	       style.setFont(font);  
	       //设置表内容格式  
	       HSSFCellStyle style2 = wb.createCellStyle();  
	       style2.setBorderBottom((short) 1);// 下边框    
	       style2.setBorderLeft((short) 1);// 左边框    
	       style2.setBorderRight((short) 1);// 右边框    
	       style2.setBorderTop((short) 1);// 上边框    
	       style2.setAlignment(HSSFCellStyle.ALIGN_CENTER);  
	       HSSFCell cell = row.createCell(0);  
	       cell.setCellValue("编号");    
	       cell.setCellStyle(style);    
	       cell = row.createCell(1);    
	       cell.setCellValue("区域查询人姓名");    
	       cell.setCellStyle(style);    
	       cell = row.createCell(2);    
	       cell.setCellValue("查询人账号");    
	       cell.setCellStyle(style);  
	       cell = row.createCell(3);    
	       cell.setCellValue("查询人身份证号码");     
	       cell.setCellStyle(style);  
	       cell = row.createCell(4);    
	       cell.setCellValue("客户姓名");    
	       cell.setCellStyle(style);  
	       cell = row.createCell(5);    
	       cell.setCellValue("客户身份证号");    
	       cell.setCellStyle(style); 
	       cell = row.createCell(6);    
	       cell.setCellValue("编码");    
	       cell.setCellStyle(style); 
	       cell = row.createCell(7);    
	       cell.setCellValue("查询成功日期");    
	       cell.setCellStyle(style); 
	       cell = row.createCell(8);    
	       cell.setCellValue("是否回寄");    
	       cell.setCellStyle(style);
	       
	      if(list!=null && list.size()>0){
	    	  int i=0;
	      for (QuicklyAddListDetails quicklyAddListDetails:list) {
           row = sheet.createRow((int) i + 1);    
           // 创建单元格，并设置值    
           row.createCell(0).setCellValue(i); 
           row.createCell(1).setCellValue(quicklyAddListDetails.getSname()); 
           row.createCell(2).setCellValue(quicklyAddListDetails.getSaccount());  
           row.createCell(3).setCellValue(quicklyAddListDetails.getSIdcard());
           row.createCell(4).setCellValue(quicklyAddListDetails.getYname());
           row.createCell(5).setCellValue(quicklyAddListDetails.getYIdcard());
           row.createCell(6).setCellValue(quicklyAddListDetails.getSqsbm());
           row.createCell(7).setCellValue(quicklyAddListDetails.getSuccessDate());
           if(!quicklyAddListDetails.getYfreturn().equals("0")){
        	   row.createCell(8).setCellValue("否");
           }else{
        	   row.createCell(8).setCellValue("是");
           }
           	i++;
	      	}	
	     } 
	      return wb;  
	}

	@Transactional(timeout = 30 ,rollbackFor=Exception.class)
	public Integer submitCirculation(LoanApplyCaseDTO param) throws MarvelsBusinessException {
		McamLoanApplyInfoDTO dto = mcamLoanApplyInfoDao.selectMcamLoanApplyInfoByLoanId(param.getLoanId());
		//LoanApplyCaseDTO dto = loanApplyCaseDao.selectByLoanId(param.getLoanId());
		Integer count=0;
		if(dto!=null){
			//如果是否为云保贷，判断是否已经截屏
			if ("1".equals(dto.getProductType())) {
				List<Map<String, String>> list = creditDao.getMoanInsurancePolicyInfo(param.getLoanId());
				if(CollectionUtils.isEmpty(list)){
					count =2;
					return count;
				}
			}
			UserDTO user = CacheUtils.getCacheUser();
			String userCode =user.getUserCode() == null?MarvelsConstant.SYSTEM_USER : user.getUserCode();
//			param.setCaseStatus(LoanStateConstant.Z00);
			param.setStatus(0);
			param.setUpdatedBy(userCode);
//			count = loanApplyCaseDao.updateByPrimaryKeySelective(param);//改变进件单 的状态
			
			LoanApplyCaseDTO caseInfoDto = commitToNextNode(param);
			//保存审批意见
			if(!CollectionUtils.isEmpty(param.getBackReasonCodes())){
				this.saveOpinion(param, MarvelsConstant.PROCESS_RESULT_OK, param.getBackReason(), OpinionConstant.OPINIONSUBMIT);
			}
			else if(!StringUtils.isEmpty(param.getBackReason())){//页面只有填备注，没有原因选项的情况
				// 记录审批意见信息
				OpinionDTO opinionDTO = new OpinionDTO();
				opinionDTO.setLoanId(param.getLoanId());
				opinionDTO.setCreatedBy(user.getUserCode());
				opinionDTO.setUpdatedBy(user.getUserCode());
				opinionDTO.setOpinion(param.getBackReason());
				opinionDTO.setNodeCode(param.getCurNodeCode());
				opinionDTO.setCaseVersion(caseInfoDto.getCaseVersion());
				opinionDTO.setOpinionClass(OpinionConstant.OPINIONSUBMIT);
				this.opinionService.saveOpinion(opinionDTO);
			}
			//修改进件状态
			String status = LoanStateConstant.Z00;
			MarvelsLogUtil.getInstance().info("截屏修改进件状态"+caseInfoDto.getAssignee());
			if(StringUtil.isNotEmpty(caseInfoDto.getAssignee())) {
				status = LoanStateConstant.Z01;
			}
			mcamLoanApplyInfoCommonService.updateMcamLoanApplyInfoStatusByLoanId(param.getLoanId(),status, null, userCode);
		}
		return count;
	}

	@Override
	public Map<String, Object> getUserCreditInfo(String loanId) throws MarvelsBusinessException {
		if(StringUtils.isEmpty(loanId)){
			throw new MarvelsBusinessException("贷款单号为空");
		}
		//用户的基本信息
		LoanApplyCaseDTO userInfo = creditReportService.getUserBaseInfoByLoanId(loanId);
		if(userInfo == null){
			throw new MarvelsBusinessException("该笔订单已退回至app或不存在");
		}
		Map<String, Object> dataMap = new HashMap<String, Object>();
		//退回原因
		List<OpinionTypeDTO> opinionTypes = getReturnOpinionTypes();
		dataMap.put("opinionTypes", opinionTypes);
		//用户影像资料附件
//		List<McamAttachmentInfoDTO> mediaList = creditReportService.getUserMediaByLoanId(loanId);
		/*List<LaAttachAtmeTypeViewDTO> mediaList = uploadFileService.getAttachmentsByViewKey(AttachmentViewKeyConstants.ZX_CUSTOMER_CHECK, loanId);*/
		List<LaAttachAtmeTypeViewDTO> mediaList = uploadFileService.getAttachmentsByViewKey(CaseNodeConstant.WOCREDITINSPECTION.getCode(), loanId);
		//影像资料
		dataMap.put("media", mediaList);
		//用户基本 信息
		dataMap.put("userInfo", userInfo);
		return dataMap;
	}
	
	private List<OpinionTypeDTO> getReturnOpinionTypes() throws MarvelsBusinessException{
		OpinionTypeDTO param = new OpinionTypeDTO();
		param.setNodeCode(CaseNodeConstant.WOCREDITINSPECTION.getCode());
		param.setPatternCode(PatternType.XIANXIAPRODUCT.getPatternTypeCode());
		List<OpinionTypeDTO> opinionTypes = opinionTypeService.findOpinionTypes(param);
		return opinionTypes;
	}

	public Map<String, Object> creReportBeforeList(LoanApplyCaseDTO param) throws MarvelsBusinessException {
		Map<String,Object> dataMap = new HashMap<String,Object>();
		param=param==null?new LoanApplyCaseDTO():param;
		param.setAssignee(param.obtainLoginUserName());
		PageInfo<LoanApplyCaseDTO> pageInfo = creditReportService.getPageInfoByCondition(param);
		//查询征信审核节点待取件数量
		Integer waitCount =creditReportService.getWaitForDealCount(param);
		dataMap.put("pageInfo", pageInfo);
		//待处理单子数量
		dataMap.put("waitCount", waitCount);
		return dataMap;
	}

	public Integer uploadFile(MultipartFile file, String loanId,String atmtTypeName,String AtmtType) throws MarvelsBusinessException, IOException {
		McamAttachmentInfoDTO attachment = new McamAttachmentInfoDTO();
		attachment.setAtmtType(AtmtType);
		attachment.setAtmtTypeName(atmtTypeName);
		List<String> supportType = new ArrayList<String>();
		supportType.add("pdf");
		supportType.add("img");
		supportType.add("png");
		supportType.add("jpg");
		supportType.add("mp3");
		supportType.add("mp4");
		supportType.add("amr");
		supportType.add("m4a");
		supportType.add("wav");
		supportType.add("wov");
		return uploadFileService.uploadFile(file, loanId, supportType, attachment);
	}

	@Override
	public PageInfo<ScreenshotsDTO> getScreenshotsList(ScreenshotsDTO param)
			throws MarvelsBusinessException {
		MarvelsLogUtil.getInstance().info("入参" + param);
		PageHelper.startPage(param.getPageNum(), param.getPageSize());
		List<ScreenshotsDTO> caseList = creditDao.getScreenshotsList(param);
		PageInfo<ScreenshotsDTO> pageInfo = new PageInfo<ScreenshotsDTO>(caseList);
		return pageInfo;

	}

	@Override
	public Integer  refusedDate(ScreenshotsDTO screenshotsDTO) throws MarvelsBusinessException {
		Integer count =0;
		try {
			screenshotsDTO.setScreenshotsBy(CacheUtils.getCacheUser().getUserName());
			screenshotsDTO.setOperatorType("2");//处理状态
			creditDao.updateMoanInsurancePolicyInfo(screenshotsDTO);
			mcamLoanApplyInfoCommonService.updateMcamLoanApplyInfoStatusByLoanId(screenshotsDTO.getLoanId(),
					LoanStateConstant.Z82, LoanStateConstant.J07, CacheUtils.getCacheUser().getUserName());
			LoanApplyCaseDTO caseInfo = loanApplyCaseDao.getEntityByLoanId(screenshotsDTO.getLoanId());
			OpinionDTO opinionDTO = new OpinionDTO();
			opinionDTO.setLoanId(screenshotsDTO.getLoanId());
			opinionDTO.setCaseVersion(caseInfo.getCaseVersion());
			opinionDTO.setCaseResult("RETURN");
			opinionDTO.setNodeCode(caseInfo.getCurNodeCode());
			opinionDTO.setNodeName(caseInfo.getCurNodeName());
			opinionDTO.setOpinionTypeCode("ERROR_CODE_BAODAN");
			opinionDTO.setOpinionTypeName("帐号密码错误");
			opinionDTO.setOpinionTypeApp("帐号密码错误");
			opinionDTO.setOpinionClass(OpinionConstant.OPINIONRETURN);
			UserDTO user = CacheUtils.getCacheUser();
			opinionDTO.setCreatedBy(user.getUserCode());
			opinionDTO.setUpdatedBy(user.getUserCode());
			opinionDTO.setOpinion("帐号密码错误退回！"); //LoanApplyCaseDTO
			opinionService.saveOpinion(opinionDTO);
			count = 1;
			return count;
		} catch (Exception e) {
		}
		return count;
	}

	@Override
	public Integer submitDate(ScreenshotsDTO screenshotsDTO) throws MarvelsBusinessException {
		Integer count= 0;
		ScreenshotsDTO casescr = creditDao.selertMoanInsurancePolicyInfo(screenshotsDTO);
		if (null == casescr) {
			count =0;
			return count;
		}
		//保存操作人，
		screenshotsDTO.setScreenshotsBy(CacheUtils.getCacheUser().getUserName());
		screenshotsDTO.setOperatorType("1");//处理状态
		creditDao.updateMoanInsurancePolicyInfo(screenshotsDTO);
		count =1;
		return count;
		
	}

	@Override
	public List<LaAttachAtmeTypeViewDTO> getAttachmentsByViewKey(String loanId) throws MarvelsBusinessException {
		/*List<LaAttachAtmeTypeViewDTO> mediaList = uploadFileService.getAttachmentsByViewKey(AttachmentViewKeyConstants.ZX_APPROVE_BEFORE, loanId);*/
		List<LaAttachAtmeTypeViewDTO> mediaList = uploadFileService.getAttachmentsByViewKey(CaseNodeConstant.WOCHECKINGBEFORE.getCode(), loanId);
		
		return mediaList;
	}

	@Override
	public Integer savaScreenshotsData(ScreenshotsDTO screenshotsDTO) throws MarvelsBusinessException {
		MarvelsLogUtil.getInstance().info("保单截屏入存开始"+   screenshotsDTO.getAtmtType() +"*****"+screenshotsDTO.getLoanId());
		Integer count =null;
		if(!StringUtils.isEmpty(screenshotsDTO.getLoanId()) && !StringUtils.isEmpty(screenshotsDTO.getFileLocation())
				&& StringUtils.isNotBlank(screenshotsDTO.getThumbnailsUrl())){
			count = creditDao.savaScreenshotsData(screenshotsDTO);
		}
		return count;
	}

	@Override
	public LoanApplyCaseDTO handleProcess(HandleProcessDTO handleProcessDTO) throws MarvelsBusinessException {
		//取件，征信4阶段
		LoanApplyCaseDTO caseDto = processService.handleProcess(handleProcessDTO);
		return caseDto;
	}

	@Override
	public Integer updateImageInfo(ScreenshotsDTO screenshotsDTO) throws MarvelsBusinessException {
		MarvelsLogUtil.getInstance().info("签名覆盖开始执行============》》》》："+screenshotsDTO);
		Integer count = null;
		if("Q_MQ".equalsIgnoreCase(screenshotsDTO.getAtmtType())&&!StringUtils.isEmpty(screenshotsDTO.getLoanId())){
			McamAcLoanApplyImageInfo dto = new McamAcLoanApplyImageInfo();
			dto.setAtmtType(screenshotsDTO.getAtmtType());
			dto.setLoanId(screenshotsDTO.getLoanId());
			dto.setDeleteFlag(1);
			//1.更新老的影像文件状态为失效
			attachmentInfoMapper.updateAttachmentStatus(dto);
			//2.新增一条影像记录
			count = this.savaScreenshotsData(screenshotsDTO);
			if(count==null||count<=0){
				throw new MarvelsBusinessException("新增附件失败！"+count);
			}
		}
		MarvelsLogUtil.getInstance().info("签名覆盖执行结束返回值============》》》》："+count);
		return count;
	}

	@Override
	public List<LoanApplyCaseDTO> findCreditList(LoanApplyCaseDTO loanApplyCaseDTO) {
		// TODO Auto-generated method stub
		PageHelper.startPage(loanApplyCaseDTO.getPageNum(), loanApplyCaseDTO.getPageSize());
		List<LoanApplyCaseDTO> loanApplyCases = creditDao.selectCreditList(loanApplyCaseDTO);
		return loanApplyCases;
	}

	@Override
	public List<McamAttachmentInfoDTO> queryContract(String loandId)throws MarvelsBusinessException {
		List<McamAttachmentInfoDTO> mapList = new ArrayList<McamAttachmentInfoDTO>();
		try {
			String pdfUrl = ServerProperties.getValue(configPropertiesPath, "resource.properties", "checkSignature.url");
			Map map = new HashMap();
			map.put("loanId", loandId);
			map.put("atmtType", "SEAL_PDF%");
			mapList = creditDao.queryContract(map);
			if(CollectionUtils.isEmpty(mapList)){
				throw new MarvelsBusinessException("暂无合同生成！");
			}
			for (McamAttachmentInfoDTO entity : mapList) {
				//查看html
				String[] atmtype = entity.getAtmtType().split("_");
				String tempUrl = pdfUrl+"/"+loandId+"/"+atmtype[2];
				entity.setFileLocation(tempUrl);//查看pdf
			}
		} catch (Exception e) {
			throw new MarvelsBusinessException("查看合同异常",e);
		}
		return mapList;
	}

	@Override
	public Page<EdcBurialPointMsgDTO> getBurialPointMsg(EdcBurialPointMsgDTO edcBurialPointMsgDTO)
			throws MarvelsBusinessException {
		if(StringUtils.isEmpty(edcBurialPointMsgDTO.getLoanId())){
			throw new MarvelsBusinessException("进件单号不能为空");
		}
		
		// 如果当前loanId取不到数据，就取复贷的，否则取当前loanId的短信
		String loanId = edcBurialPointMsgDTO.getLoanId();
		if(edcBurialPointMsgDao.selectCountByLoanId(edcBurialPointMsgDTO.getLoanId()) == 0){
			loanId = thirdCreditReportService.getThirdLoanId(edcBurialPointMsgDTO.getLoanId());
		}
		
		edcBurialPointMsgDTO.setLoanId(loanId);
		Integer pageNum=edcBurialPointMsgDTO.getPageNum();
		Integer pageSize=edcBurialPointMsgDTO.getPageSize();
		if(pageSize!=null && pageSize!=null){
			PageHelper.startPage(pageNum, pageSize);
		}
		if(StringUtils.isNotEmpty(edcBurialPointMsgDTO.getMessageKeywords())){
			List<String> list=Arrays.asList(edcBurialPointMsgDTO.getMessageKeywords().split(","));
			edcBurialPointMsgDTO.setMessageKeyword(list);
		}
		return edcBurialPointMsgDao.selectByLoanId(edcBurialPointMsgDTO);
	}

}
